package resolver

// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.

import (
	"context"
	"errors"
	"fmt"
	"strconv"

	"mall/service/blog/rpc/blogclient"
	"mall/service/wpgql/api/internal/graph/generated"
	"mall/service/wpgql/api/internal/graph/helper"
	"mall/service/wpgql/api/internal/graph/model"
	"mall/service/wpgql/api/internal/graph/util"
)

const blogBookSingleError = "could not get knowledgeBase entry"
const blogBookListError = "could not list knowledgeBase entries"

func (r *bookResolver) Categories(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToCategoryConnectionWhereArgs,
) (*model.BookToCategoryConnection, error) {
	if where == nil {
		return obj.Categories, nil
	}

	return &model.BookToCategoryConnection{}, nil
}

func (r *bookResolver) Comments(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToCommentConnectionWhereArgs,
) (*model.BookToCommentConnection, error) {
	if where == nil {
		return obj.Comments, nil
	}

	return &model.BookToCommentConnection{}, nil
}

func (r *bookResolver) Content(ctx context.Context, obj *model.Book, format *model.PostObjectFieldFormatEnum) (*string, error) {
	var content string
	if obj != nil {
		if obj.Content != nil {
			content = *obj.Content
		}
	}

	return &content, nil
}

func (r *bookResolver) EnqueuedScripts(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
) (*model.ContentNodeToEnqueuedScriptConnection, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *bookResolver) EnqueuedStylesheets(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
) (*model.ContentNodeToEnqueuedStylesheetConnection, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *bookResolver) Relations(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToRelationConnectionWhereArgs,
) (*model.BookToRelationConnection, error) {
	if where == nil {
		return obj.Relations, nil
	}

	return &model.BookToRelationConnection{}, nil
}

func (r *bookResolver) Revisions(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToRevisionConnectionWhereArgs,
) (*model.BookToRevisionConnection, error) {
	if where == nil {
		return obj.Revisions, nil
	}

	return &model.BookToRevisionConnection{}, nil
}

func (r *bookResolver) Sections(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToSectionConnectionWhereArgs,
) (*model.BookToSectionConnection, error) {
	if where == nil {
		return obj.Sections, nil
	}

	return &model.BookToSectionConnection{}, nil
}

func (r *bookResolver) Tags(
	ctx context.Context,
	obj *model.Book,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.BookToTagConnectionWhereArgs,
) (*model.BookToTagConnection, error) {
	if where == nil {
		return obj.Tags, nil
	}

	return &model.BookToTagConnection{}, nil
}

func (r *bookResolver) Title(ctx context.Context, obj *model.Book, format *model.PostObjectFieldFormatEnum) (*string, error) {
	var title string
	if obj != nil {
		if obj.Title != nil {
			title = *obj.Title
		}
	}

	return &title, nil
}

func (r *mutationResolver) CreateBook(ctx context.Context, input model.CreateBookInput) (*model.CreateBookPayload, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *mutationResolver) DeleteBook(ctx context.Context, input model.DeleteBookInput) (*model.DeleteBookPayload, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *mutationResolver) UpdateBook(ctx context.Context, input model.UpdateBookInput) (*model.UpdateBookPayload, error) {
	panic(fmt.Errorf("not implemented"))
}

func (r *queryResolver) Book(
	ctx context.Context,
	id string,
	idType *model.BookIDType,
	asPreview *bool,
) (*model.Book, error) {
	req := &blogclient.BookDetailReq{}

	var preview bool
	if asPreview != nil {
		preview = *asPreview
	}
	req.AsPreview = preview

	preload, eagerLoad := helper.GetBlogBookPreloads(ctx)
	if preload != "" {
		req.Preload = preload
	}
	if eagerLoad != "" {
		req.EagerLoad = eagerLoad
	}
	filter := helper.GetBlogBookFilter(id, idType)
	if filter != "" {
		req.Filter = filter
	}

	res, err := r.svcCtx.BlogRpc.BookDetail(ctx, req)
	if err != nil {
		return nil, errors.New(blogBookSingleError)
	}

	return helper.BlogBookToGraphQL(res), nil
}

func emptyRootQueryToBookConnection() *model.RootQueryToBookConnection {
	return &model.RootQueryToBookConnection{
		Edges:    []*model.RootQueryToBookConnectionEdge{},
		Nodes:    []*model.Book{},
		PageInfo: &model.WPPageInfo{},
	}
}

func (r *queryResolver) Books(
	ctx context.Context,
	first *int,
	last *int,
	after *string,
	before *string,
	where *model.RootQueryToBookConnectionWhereArgs,
) (*model.RootQueryToBookConnection, error) {
	req := &blogclient.BookListReq{}

	preload, eagerLoad := helper.GetBlogBookNodesPreloads(ctx)
	if preload == "" && eagerLoad == "" {
		preload, eagerLoad = helper.GetBlogBookNodePreloads(ctx)
	}
	if preload != "" {
		req.Preload = preload
	}
	if eagerLoad != "" {
		req.EagerLoad = eagerLoad
	}

	pagination := util.NewPagination(first, last, after, before,
		r.svcCtx.Config.Query.DefaultAmount, r.svcCtx.Config.Query.MaxAmount)

	var sorter []*model.PostObjectsConnectionOrderbyInput
	if where != nil {
		sorter = where.Orderby
	}
	sorterMap := helper.GetBlogPostConnectionSorterMap(pagination, sorter)
	var reverse bool
	if sorterMap != nil {
		for k, v := range sorterMap {
			switch k {
			case "offset":
				if i, err := strconv.ParseInt(v, 10, 32); err == nil {
					req.Offset = int32(i)
				}
			case "limit":
				if i, err := strconv.ParseInt(v, 10, 32); err == nil {
					req.Limit = int32(i)
				}
			case "sorter":
				req.Sorter = v
			case "reverse":
				if v == "1" {
					reverse = true
				}
			}
		}
	}

	filterMap := helper.GetBlogBookConnectionFilterMap(where)
	if filterMap != nil {
		for k, v := range filterMap {
			switch k {
			case "search":
				req.Search = v
			case "filter":
				req.Filter = v
			case "preFilterEntity":
				req.PreFilterEntity = v
			case "preFilter":
				req.PreFilter = v
			}
		}
	}
	req.PreFilterEntity = "blogTerm"
	req.PreFilter = "Slug,equalTo:perfumes;Taxonomy,equalTo:11"

	res, err := r.svcCtx.BlogRpc.BookList(ctx, req)
	if err != nil {
		return &model.RootQueryToBookConnection{}, errors.New(blogBookListError)
	}

	if len(res.Data) > 0 {
		var entries []*model.Book
		for _, entry := range res.Data {
			entries = append(entries, helper.BlogBookToGraphQL(entry))
		}
		connection := helper.GetRootQueryToBookConnection(entries,
			res.HasNextPage > 0, res.HasPreviousPage > 0, req.Offset, reverse)
		return connection, nil
	}

	return emptyRootQueryToBookConnection(), nil
}

// Book returns generated.BookResolver implementation.
func (r *Resolver) Book() generated.BookResolver { return &bookResolver{r} }

type bookResolver struct{ *Resolver }
